package com.raos.example.thread.controller;

import com.raos.example.thread.task.AsyncTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 异步任务非同步 controller
 *
 * @author raos
 * @email 991207823@qq.com
 * @date 2022/6/16 09:44
 */
@RestController
@RequestMapping("/async")
@Slf4j
public class AsyncController {

    @Autowired
    private AsyncTask asyncTask;
    @Resource(name = "otherPoolTaskExecutor")
    private ThreadPoolTaskExecutor executor;
    private Random random = new Random();

    @RequestMapping("/task")
    public void task() throws InterruptedException {
        long start = System.currentTimeMillis();
        asyncTask.task1();
        asyncTask.task2();
        Thread.sleep(1000);

        long end = System.currentTimeMillis();
        log.info("main cost {} ms", end - start);
    }

    @PostMapping("/sendSms")
    public String sendSms(Integer num) {
        if (ObjectUtils.isEmpty(num)) {
            num = 1;
        }
        final AtomicInteger success = new AtomicInteger();
        final CountDownLatch countDownLatch = new CountDownLatch(num);
        try {
            for (int i = 1; i <= num; i++) {
                int finalI = i;
                executor.execute(() -> {
                    try {
                        int nextInt = getRandomNum();
                        TimeUnit.MILLISECONDS.sleep(nextInt);
                        log.info("发送第[{}]条短信消息,随机耗时毫秒数[{}]...", finalI, nextInt);
                        success.getAndIncrement();
                    } catch (InterruptedException e) {
                        log.error("短信消息发送失败", e);
                        Thread.currentThread().interrupt();
                    } finally {
                        countDownLatch.countDown();
                    }
                });
            }
            countDownLatch.await();
        } catch (InterruptedException e) {
            log.error("批量短信异常", e);
            Thread.currentThread().interrupt();
        }
        int i = success.get();
        String msg = String.format("消息发送成功数=%s,失败数=%s", i, num-i);
        log.info(msg);
        return msg;
    }

    private Integer getRandomNum() {
        int nextInt = random.nextInt(200);
        if (nextInt < 50) {
            return getRandomNum();
        }
        return nextInt;
    }

}
